//
//  GGBLEManager.m
//  03-CL-Lock
//
//  Created by 陈志勇 on 16/9/23.
//  Copyright © 2016年 陈志勇. All rights reserved.
//

#import "GGBLEManager.h"


@interface GGBLEManager()

/**  保存接收到的数据  */
@property(strong,nonatomic) NSMutableData *receiveData;
/**  此次返回数据计数器  */
@property(assign,nonatomic) NSInteger receiveDataCount;
/**  是否第一次接收  */
@property(assign,nonatomic) BOOL isFirst;

@end

@implementation GGBLEManager
// 懒加载
- (NSMutableData *)receiveData{
    if (_receiveData == nil) {
        _receiveData = [NSMutableData data];
    }
    return _receiveData;
}

// 创建单例类
+(instancetype)getInstance{
    static GGBLEManager * manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[GGBLEManager alloc]init];
        
    });
    return manager;
}

#pragma mark - 蓝牙相关操作;
//开始扫描
- (void)startScan{
    //初始化中心，并设置其代理
    _theManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    //初始化外设列表
    _peripheralList = [[NSMutableArray alloc] initWithCapacity:0];
}

//停止扫描
- (void)stopScan{
    [_theManager stopScan];
}

//获取蓝牙列表
-(NSMutableArray *)getNameList{
    return _peripheralList;
}

//连接外设
-(void)connectPeripheralWith:(CBPeripheral *)per{
    if (per != nil) {
        //清空数据再进行连接
        _thePeripheral = nil;
        _writeCha = nil;
        _notifyCha = nil;
        _isFirst = YES;
        [_theManager connectPeripheral:per options:nil];
    }
}

//打开通知
-(void)openNotify:(CBCharacteristic *)cha{
//    if (_notifyCha!=nil&&_thePeripheral!=nil) {
//        [_thePeripheral setNotifyValue:YES forCharacteristic:cha];
//        NSLog(@"%s,%d,%@",__func__,__LINE__,_thePeripheral);
//    }
    if (cha!=nil&&_thePeripheral!=nil) {
        [_thePeripheral setNotifyValue:YES forCharacteristic:cha];
        NSLog(@"%s,%d,%@",__func__,__LINE__,_thePeripheral);
    }
}

//关闭通知
-(void)cancelNotify
{
    [_thePeripheral setNotifyValue:NO forCharacteristic:_notifyCha];
    
}

//断开连接
-(void)cancelPeripheralWith:(CBPeripheral *)per
{
    [_theManager cancelPeripheralConnection:_thePeripheral];
    
}

//蓝牙连接状态回调
- (void)connectInfoReturn:(void (^)(CBCentralManager *, CBPeripheral *, NSString *))myBlock{
    
    _conReturnBlock = [myBlock copy];
    
}

//蓝牙外设列表回调
-(void)getBlueListArray:(void (^)(NSMutableArray *blueToothArray))listBlock{
    
    _bluetoothListArr = [listBlock copy];
}

//蓝牙收到数据回调
-(void)responseReturn:(void(^)(NSData *responseData))myData{
    
    _responseDataReturnBlock = [myData copy];
}

//发送数据
- (void)sendData:(NSData *)infoData{
    
//    NSLog(@"蓝牙发送：%@",infoData);
    
    if (_thePeripheral && _writeCha)
    {
        [_thePeripheral writeValue:infoData forCharacteristic:_writeCha type:CBCharacteristicWriteWithoutResponse];
        
    }
}

#pragma mark - CBCentralManagerDelegate\CBPeripheralDelegate
// 检测蓝牙状态
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    
    /*!
     *  @enum CBCentralManagerState
     *
     *  @discussion Represents the current state of a CBCentralManager.
     *
     *  @constant CBCentralManagerStateUnknown       State unknown, update imminent.
     *  @constant CBCentralManagerStateResetting     The connection with the system service was momentarily lost, update imminent.
     *  @constant CBCentralManagerStateUnsupported   The platform doesn't support the Bluetooth Low Energy Central/Client role.
     *  @constant CBCentralManagerStateUnauthorized  The application is not authorized to use the Bluetooth Low Energy Central/Client role.
     *  @constant CBCentralManagerStatePoweredOff    Bluetooth is currently powered off.
     *  @constant CBCentralManagerStatePoweredOn     Bluetooth is currently powered on and available to use.
     *
     */
    
    switch (central.state) {
        case CBCentralManagerStateUnknown:
            NSLog(@"CBCentralManagerStateUnknown");
            break;
        case CBCentralManagerStateResetting:
            NSLog(@"CBCentralManagerStateResetting");
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@"CBCentralManagerStateUnsupported");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"CBCentralManagerStateUnauthorized");
            break;
        case CBCentralManagerStatePoweredOff:
            NSLog(@"CBCentralManagerStatePoweredOff");
            break;
        case CBCentralManagerStatePoweredOn:
            
            //当检测到蓝牙处于打开状态，则进行扫描
//            [_theManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:KEY_SERVICE_UUID],
//                                                          [CBUUID UUIDWithString:LOCK_SERVICE_UUID]] options:nil];
            [_theManager scanForPeripheralsWithServices:nil options:nil];
            NSLog(@"CBCentralManagerStatePoweredOn");
            break;
        default:
            break;
    }
    
}

//扫描外设
- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary<NSString *,id> *)advertisementData
                  RSSI:(NSNumber *)RSSI{
    // 过滤信号强度范围
    if (RSSI.integerValue > -1) return;
    if (RSSI.integerValue < -90) return;
    
    //发现外设就添加到外设列表中
    if (peripheral.name != nil && ![_peripheralList containsObject:peripheral]) {
        NSLog(@"发现蓝牙设备：%@,%@",peripheral,RSSI);
        NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:peripheral,@"peripheral",
                                                                       RSSI,@"RSSI",
                                                                    nil];
        [_peripheralList addObject:dic];
    }
    
    // 蓝牙外设列表回调
    if (_bluetoothListArr) {
        _bluetoothListArr(_peripheralList);
    }
}

//连接失败
- (void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral *)peripheral
                 error:(NSError *)error{
    
    if (_conReturnBlock) {
        _conReturnBlock(central,peripheral,@"ERROR");
    }
    
}

//断开连接
- (void)centralManager:(CBCentralManager *)central
didDisconnectPeripheral:(CBPeripheral *)peripheral
                 error:(NSError *)error{
    
    if (_conReturnBlock) {
        _conReturnBlock(central,peripheral,@"DISCONNECT");
    }
    NSLog(@"%s,%d,蓝牙连接断开",__func__,__LINE__);
}

//连接外设成功后调用
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    _thePeripheral = peripheral;
    _thePeripheral.delegate = self;
    [peripheral discoverServices:nil];
    
}

//扫描服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    if (error) {
        NSLog(@"%s,%d",__func__,__LINE__);
        return;
    }
    
    for (CBService *ser in peripheral.services) {
        
        [peripheral discoverCharacteristics:nil forService:ser];
        
    }
    
    
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    
    
    if (error) {
        NSLog(@"%s,%d",__func__,__LINE__);
        return;
    }
    
    for (CBCharacteristic *characteristic in service.characteristics) {
        /**
         *  易索蓝牙钥匙
         */
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:KEY_CHARACTERISTIC_UUID_WHITE]]) {
            _writeCha = characteristic;
        }
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:KEY_CHARACTERISTIC_UUID_READ]]) {
            _notifyCha = characteristic;
            [self openNotify:characteristic];
            NSLog(@"发现特征值：%@",characteristic);
        }
        /**
         *  创力蓝牙锁
         */
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:LOCK_CHARACTERISTIC_UUID_READWHITE]]) {
            _writeCha = characteristic;
            [self openNotify:characteristic];
            NSLog(@"发现特征值：%@",characteristic);
        }
        
        /**
         *  生久山东蓝牙
         */
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:SDTT_CHARACTERISTIC_UUID_WHITE]]) {
            _notifyCha = characteristic;
            [self openNotify:characteristic];
            NSLog(@"发现特征值：%@",characteristic);
        }
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:SDTT_CHARACTERISTIC_UUID_READ]]) {
            _writeCha = characteristic;
        }

        
    }
    
    // 判断是否有读写特征，没有则跳出；
    if (_writeCha == nil) {
        return;
    }
    //连接外设并成功扫描到外设的服务特征后回调函数
    if (_conReturnBlock) {
        _conReturnBlock(nil,peripheral,@"SUCCESS");
    }
    
}

// 一旦蓝牙收到通知就调用该方法
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@"%s,%d",__func__,__LINE__);
        return;
    }
    
    NSLog(@"收到蓝牙数据：%@",characteristic.value);
    
    // 通知block数据已经接收完成可以做事情了
    if (_responseDataReturnBlock) {
        self.responseData = characteristic.value;
        _responseDataReturnBlock(self.responseData);
    }
//    [self processData:characteristic.value];
    
}


//分包发送蓝牙数据
-(void)sendMsgWithSubPackage:(NSData*)msgData
{
    for (int i = 0; i < [msgData length]; i += QD_BLE_SEND_MAX_LEN) {
        
        // 预加 最大包长度，如果依然小于总数据长度，可以取最大包数据大小
        if ((i + QD_BLE_SEND_MAX_LEN) < [msgData length]) {
            NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, QD_BLE_SEND_MAX_LEN];
            NSData *subData = [msgData subdataWithRange:NSRangeFromString(rangeStr)];
            [self sendData:subData];
            //根据接收模块的处理能力做相应延时
            usleep(20 * 1000);
        }
        else {
            NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, (int)([msgData length] - i)];
            NSData *subData = [msgData subdataWithRange:NSRangeFromString(rangeStr)];
            
            [self sendData:subData];
            usleep(20 * 1000);
        }
    }
}

// 处理蓝牙收到的数据
- (void)processData:(NSData *)data{
    // 判断返回数据是否已经完整
    if (self.isFirst) { //第一次取出接收数据的字节长度
        Byte *resultData = (Byte *)[data bytes];
        // 取出命令长度
        unsigned char pklen = resultData[4];
        if (pklen < 16) { //小于16表示接收完成
            self.receiveDataCount = 0;
        }else{
            self.receiveDataCount = (pklen - 15) / 20 + 1;
        }
        self.isFirst = NO;
    }
    
    // 拼接收到的数据
    [self.receiveData appendData:data];
    
    if (self.receiveDataCount == 0){// 数据接收完成
        NSLog(@"数据接收完成");
        // 通知block数据已经接收完成可以做事情了
        if (_responseDataReturnBlock) {
            self.responseData = self.receiveData;
            _responseDataReturnBlock(self.responseData);
        }
        self.isFirst = YES;//数据接收完成后还原
        self.receiveData = nil; //数据接收完成还原
        
    }else{// 数据未接收完成，计数器减1
        self.receiveDataCount -= 1;
    }
}

@end
